﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.IO;
using System.Data.Common;
using System.Xml;
using System.Diagnostics;

namespace Microsoft.JCI.Common.GenerateFunc
{
    class Program
    {
        static Dictionary<int, string> Funs = new Dictionary<int, string>();

        static void Main(string[] args)
        {
            StringBuilder s = new StringBuilder();
            //s.AppendLine("Delete from Jci_Sys_UserFunctionRelation");
            s.AppendLine("Delete from Jci_Sys_RoleFunctionRelation ");
            s.AppendLine("Delete from Jci_Sys_UserRoleRelation ");
            s.AppendLine("Delete from Jci_Sys_Function");
            s.AppendLine("Delete from Jci_Sys_Role ");
            s.AppendLine();
            s.Append(GenerateFunc());
            s.Append(GenerateRole());
            s.Append(GenerateRoleFunction());

            s.Append(GenerateUserRole());
            File.WriteAllText("InitPermission.sql", s.ToString());

            //Database db = DatabaseFactory.CreateDatabase();
            //DbCommand dbCommand = db.GetSqlStringCommand(s.ToString());
            //db.ExecuteNonQuery(dbCommand);

            System.Diagnostics.Process.Start("notepad.exe", "InitPermission.sql");
        }
        #region Function
        static string GenerateFunc()
        {
            List<string> OutPut = new List<string>();

            XmlDocument doc = new XmlDocument();
            doc.Load("../../Function.xml");

            XmlNodeList nl = doc.GetElementsByTagName("Root");
            foreach (XmlNode node in nl[0].ChildNodes)
            {
                FindChild(ref OutPut, node, "NULL");
            }

            StringBuilder sb = new StringBuilder();
            foreach (string str in OutPut)
            {
                sb.AppendLine(str);
            }
            sb.AppendLine("");
            return sb.ToString();
        }
        static void FindChild(ref List<string> output, XmlNode node, string ParentCode)
        {
            output.Add(MakeSqlString(node, ParentCode));

            foreach (XmlNode n in node.ChildNodes)
            {
                FindChild(ref output, n, node.Attributes["FunCode"].Value.ToString());
            }
        }
        static string MakeSqlString(XmlNode node, string Parent)
        {
            string SQL = @"IF EXISTS({2})
UPDATE Jci_Sys_Function SET {0} 
ELSE
INSERT INTO [Jci_Sys_Function] ([FuncId],[FFuncId],[FuncName],[IsMenu],[URL],[ImageUrl],[Target]	,[Description],deleted)  VALUES {1}";
            string FuncId = "'" + node.Attributes["FunCode"].Value.ToString() + "'";
            string FFuncId = "'" + Parent + "'";
            if (Parent.ToLower() == "null")
            {
                FFuncId = "NULL";
            }
            string FuncName = "N'" + node.Attributes["Name"].Value.ToString() + "'";
            string m = node.Attributes["IsMenu"].Value.ToString() == "true" ? "1" : "0";
            string IsMenu = "'" + m + "'";
            string URL = "'" + node.Attributes["URL"].Value.ToString() + "'";
            string ImageUrl = "'" + node.Attributes["ImageUrl"].Value.ToString() + "'";
            string Target = "'" + node.Attributes["Target"].Value.ToString() + "'";
            string Description = "NULL";
            //string CreatedOn = "getdate()";
            //string CreatedBy = "'System'";
            //string LastModifiedOn = "getdate()";
            //string LastModifiedBy = "'System'";

            string sfun = node.Attributes["FunCode"].Value.ToString();

            int funid = Convert.ToInt32(sfun.Replace("Func", ""));
            Funs.Add(funid, FuncId);

            string SQL2 = "(" + FuncId + "," + FFuncId + "," + FuncName + "," + IsMenu + ","
                            + URL + "," + ImageUrl + "," + Target + "," + Description + ",0)";

            string SQL3 = " FFuncId=" + FFuncId + ",FuncName=" + FuncName + ",IsMenu=" + IsMenu + ",URL=" + URL + ",ImageUrl=" + ImageUrl + ",Target=" + Target + ",Description=" + Description + " where FuncId=" + FuncId;
            string sql4 = "select 1 from Jci_Sys_Function where FuncId=" + FuncId;
            return string.Format(SQL, SQL3, SQL2, sql4);
        }
        #endregion

        #region Role
        static string GenerateRole()
        {
            List<string> OutPut = new List<string>();

            XmlDocument doc = new XmlDocument();
            doc.Load("../../RoleFunction.xml");

            XmlNodeList nl = doc.GetElementsByTagName("Root");
            foreach (XmlNode node in nl[0].ChildNodes)
            {
                OutPut.Add(GenerateRoleSQL(node));
            }


            StringBuilder sb = new StringBuilder();
            foreach (string str in OutPut)
            {
                sb.AppendLine(str);
            }
            sb.AppendLine("");
            return sb.ToString();

        }
        static string GenerateRoleSQL(XmlNode node)
        {
            string SQL = "INSERT INTO [Jci_sys_Role] ([RoleId],[RoleName],[RoleDesc],[IsSystem],[Deleted],[CreatedOn]) VALUES";

            string RoleId = "N'" + node.Attributes["GUID"].Value.ToString() + "'";
            string RoleName = "N'" + node.Attributes["Name"].Value.ToString() + "'";
            string Description = "N'" + node.Attributes["Desc"].Value.ToString() + "'";
            string SystemCode = "NULL";
            if (node.Attributes["SystemCode"] != null)
                SystemCode = "N'" + node.Attributes["SystemCode"].Value.ToString() + "'";

            string IsSystem = "'" + node.Attributes["IsSys"].Value.ToString() + "'";
            string Deleted = "0";
            string CreatedOn = "getdate()";

            string SQL2 = "(" + RoleId + "," + RoleName + "," + Description + "," + IsSystem + ","
                             + Deleted + ","
                            + CreatedOn + ")";


            return SQL + SQL2;

        }
        #endregion

        #region Role Function
        static string GenerateRoleFunction()
        {
            List<string> OutPut = new List<string>();

            XmlDocument doc = new XmlDocument();
            doc.Load("../../RoleFunction.xml");

            XmlNodeList nl = doc.GetElementsByTagName("Root");

            //find role
            foreach (XmlNode node in nl[0].ChildNodes)
            {
                string RoleID = node.Attributes["GUID"].Value;
                //find func
                foreach (XmlNode n in node.ChildNodes)
                {
                    if (n.Name.ToUpper() == "FUNCPOINT")
                    {
                        string id = n.Attributes["ID"].Value;
                        if (id.Length == 0)
                            continue;
                        OutPut.Add(GenerateRoleFuncSql(RoleID, Convert.ToInt32(id)));
                    }
                    if (n.Name.ToUpper() == "FUNCREGION")
                    {
                        string from = n.Attributes["From"].Value;
                        string to = n.Attributes["To"].Value;
                        string denyFuncs = "";
                        if (n.Attributes["Deny"] != null)
                            denyFuncs = n.Attributes["Deny"].Value;
                        List<string> lstr = GenerateRoleFuncSql(RoleID, Convert.ToInt32(from), Convert.ToInt32(to), denyFuncs);
                        foreach (string s in lstr)
                        {
                            OutPut.Add(s);
                        }
                    }

                }
            }

            StringBuilder sb = new StringBuilder();
            foreach (string str in OutPut)
            {
                sb.AppendLine(str);
            }
            sb.AppendLine("");
            return sb.ToString();
        }

        static string GenerateRoleFuncSql(string Role, int Fun)
        {

            string SQL = "INSERT INTO [Jci_Sys_RoleFunctionRelation] ([ID],[RoleId],[FuncId],Deleted) VALUES";

            string RoleFunctionId = "'" + Guid.NewGuid().ToString() + "'";
            string RoleId = "'" + Role + "'";
            string FuncId = Funs[Fun];

            string SQL2 = "(" + RoleFunctionId + "," + RoleId + "," + FuncId + ",0)";

            return SQL + SQL2;
        }
        static string GenerateRoleFuncSql(string Role, string Fun)
        {

            string SQL = "INSERT INTO [Jci_Sys_RoleFunctionRelation] ([ID],[RoleId],[FuncId],Deleted) VALUES";

            string RoleFunctionId = "'" + Guid.NewGuid().ToString() + "'";
            string RoleId = "'" + Role + "'";
            string FuncId = Fun;

            string SQL2 = "(" + RoleFunctionId + "," + RoleId + "," + FuncId + ",0)";

            return SQL + SQL2;
        }

        static List<string> GenerateRoleFuncSql(string Role, int from, int to, string denyFuncs)
        {
            List<string> ret = new List<string>();

            int[] arr = new int[Funs.Keys.Count];
            Funs.Keys.CopyTo(arr, 0);

            for (int i = 0; i < arr.Length; i++)
            {
                int funcId = arr[i];
                if (funcId >= from && funcId <= to && !denyFuncs.Contains(";" + funcId + ";"))
                {
                    ret.Add(GenerateRoleFuncSql(Role, Funs[arr[i]]));
                }
            }

            return ret;
        }
        #endregion

        #region userrole

        static string GenerateUserRole()
        {
            List<string> OutPut = new List<string>();

            XmlDocument doc = new XmlDocument();
            doc.Load("../../UserRole.xml");

            XmlNodeList nl = doc.GetElementsByTagName("Root");

            //find role
            foreach (XmlNode node in nl[0].ChildNodes)
            {
                string RoleID = node.Attributes["GUID"].Value;
                //find func
                foreach (XmlNode n in node.ChildNodes)
                {
                    if (n.Name.ToUpper() == "USER")
                    {
                        string id = n.Attributes["UserID"].Value;
                        OutPut.Add(GenerateUserRoleSQL(RoleID, id));
                    }
                }
            }

            StringBuilder sb = new StringBuilder();
            foreach (string str in OutPut)
            {
                sb.AppendLine(str);
            }
            sb.AppendLine("");
            return sb.ToString();


        }

        static string GenerateUserRoleSQL(string Roleid, string NtAccount)
        {
            string sql = "INSERT INTO [Jci_Sys_UserRoleRelation]([ID],[RoleId],[UserID]) VALUES ";

            string key = "'" + Guid.NewGuid().ToString() + "'";
            string role = "'" + Roleid + "'";
            string emp = "'" + NtAccount + "'";

            string sql2 = "(" + key + "," + role + "," + emp + ")";

            return sql + sql2;
        }
        #endregion
    }
}
